package org.mtmi.io.controls;

import java.io.IOException;

import net.n3.nanoxml.IXMLElement;

import org.mtmi.io.ReaderError;
import org.mtmi.io.SceneReader;
import org.mtmi.io.SceneWriter;
import org.mtmi.io.XMLReader;
import org.mtmi.io.XMLWriter;
import org.mtmi.ui.IAdaptable;
import org.mtmi.ui.controls.Control;
import org.mtmi.ui.controls.IValueGenerator;
import org.mtmi.ui.controls.Keyboard;
import org.mtmi.ui.controls.midi.MidiKeyboard;

/**
 * In addition to {@link Keyboard}, save {@link MidiKeyboard} features:
 * <ul>
 * <li> MIDI output 
 * <li> MIDI channel
 * <li> MIDI velocity
 * <li> MIDI instrument
 * </ul>
 */
public class MidiKeyboardIO extends KeyboardIO
{
	
	private static final String E_MIDI_KEYBOARD = "midiKeyboard"; //$NON-NLS-1$
	private static final String A_OU = "output"; //$NON-NLS-1$
	private static final String A_CH = "channel"; //$NON-NLS-1$
	private static final String A_VL = "velocity"; //$NON-NLS-1$
	private static final String A_IN = "instrument"; //$NON-NLS-1$
	private static final String A_IC = "instrumentController"; //$NON-NLS-1$
	private static final String A_ICCID = "instrumentControllerCID"; //$NON-NLS-1$

	public MidiKeyboardIO() {
		//Not:yet: setProcessFeature( F_BACKGROUND_COLOR, true );
		//Not:yet: setProcessFeature( F_FOREGROUND_COLOR, true );
	}
	
	@Override
	public void writeControl( Control c, XMLWriter w, SceneWriter sw ) throws IOException 
	{
		super.writeControl(c, w, sw);
		
		//keyboard:
		MidiKeyboard kb = (MidiKeyboard)c;
		boolean ai = w.setAttributeIndented( false );
		w.startElement( E_MIDI_KEYBOARD );
		w.addAttr( A_OU, kb.getMidiOutput() );
		w.addAttr( A_CH, kb.getMidiChannel() );
		w.addAttr( A_VL, kb.getMidiVelocity() );
		w.addAttr( A_IN, kb.getMidiInstrument() );
		if( kb.getMidiInstrumentController()!=null ) {
			IValueGenerator vg = kb.getMidiInstrumentController();
			String cid = kb.getMidiInstrumentControllerConnectionId(); 
			if( vg instanceof IAdaptable ) {
				IAdaptable adp = (IAdaptable)vg;
				Control control = (Control)adp.getAdapter( Control.class, cid );
				if( control !=null ) {
					w.addAttr( A_IC, sw.getControlId( control) );
					w.addAttr( A_ICCID, cid, (String)null );
				}
			}
		}
		w.setAttributeIndented( ai );
		w.endElement( E_MIDI_KEYBOARD );
	}
	
	@Override
	public void readControl( Control c, IXMLElement element, XMLReader r, SceneReader sr ) throws ReaderError 
	{
		super.readControl(c, element, r, sr);
		
		MidiKeyboard kb = (MidiKeyboard)c;
		
		//keyboard:		
		IXMLElement e = r.getElement( element, E_MIDI_KEYBOARD, true );
		
		kb.setMidiOutput( r.getAttrInt( e, A_OU ) );
		kb.setMidiChannel( r.getAttrInt( e, A_CH ) );
		kb.setMidiVelocity( r.getAttrInt( e, A_VL ) );
		kb.setMidiInstrument( r.getAttrInt( e, A_IN ) );
		
		int id = r.getAttr( e, A_IC, 0 );
		if( id > 0 ) {
			Control ic = sr.getControl( id );
			String cid = r.getAttr( e, A_ICCID, (String)null );
			//if( ic instanceof IAdaptable ) {
			IAdaptable adp = ic;
			IValueGenerator vg = (IValueGenerator)adp.getAdapter( IValueGenerator.class, cid );
			kb.setMidiInstrumentController( vg, cid );
			//}
		}
	}
}
